﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Results_Comparer
{

    public class ContentFormatter
    {
        // Fields
        private StreamWriter f_add;
        private StreamWriter f_all;
        private StreamWriter f_del;

        // Methods
        public void addAdditions()
        {
            this.createDisplay(Difference.additions, "Added", "added");
        }

        private void addAttributes(StreamWriter f, List<RdfAttribute> mylist)
        {
            foreach (RdfAttribute attribute in mylist)
            {
                if (attribute.attributeName != null)
                {
                    f.Write("<tr>");
                    f.Write("<td class=namecolumn>" + attribute.attributeName + "</td>");
                    if (attribute.changeType.Equals("L"))
                    {
                        if (attribute.attributeOldPath == null)
                        {
                            f.Write("<td class=twocolumns>" + attribute.attributeOldValue + "</td>\n");
                        }
                        else
                        {
                            f.Write("<td class=twocolumns>" + attribute.attributeOldPath + " (" + attribute.attributeOldValue + ")</td>\n");
                        }
                    }
                    else
                    {
                        f.Write("<td class=twocolumns>" + attribute.attributeOldValue + "</td>\n");
                    }
                    if (attribute.changeType.Equals("L"))
                    {
                        if (attribute.attributeNewPath == null)
                        {
                            f.Write("<td class=twocolumns>" + attribute.attributeNewValue + "</td>\n");
                        }
                        else
                        {
                            f.Write("<td class=twocolumns>" + attribute.attributeNewPath + " (" + attribute.attributeNewValue + ")</td>\n");
                        }
                    }
                    else
                    {
                        f.Write("<td class=twocolumns>" + attribute.attributeNewValue + "</td>\n");
                    }
                    f.Write("</tr>");
                }
            }
        }

        private void addAttributesTable(StreamWriter addf)
        {
            addf.Write("<tr>");
            addf.Write("<td class=namecolumntitle>Attribute</td>");
            addf.Write("<td class=modTwoColumnsTitle>Old Value</td>\n");
            addf.Write("<td class=modTwoColumnsTitle>New Value</td>\n");
            addf.Write("</tr>");
        }

        public void addChanges()
        {
            this.createDisplay(Difference.changes, "Changed", "changed");
        }

        public void addDeletions()
        {
            this.createDisplay(Difference.deletions, "Deleted", "deleted");
        }

        private void addRdfIdTable(StreamWriter f, RdfId td)
        {
            f.Write("<tr><td class=namecolumn>RDFID</td>\n");
            f.Write("<td class=twocolumns>" + td.GetRdfId() + "</td>\n");
            f.Write("<td class=twocolumns>" + td.rdfType + "</td></tr>\n");
            f.Write("</table>\n");
        }

        private void addTableHeader(StreamWriter f)
        {
            f.Write("<table frame=box border=1 cellspacing=0 bordercolordark=white bordercolorlight=gray width=80%>");
        }

        public void BuildHTMLFoot(StreamWriter f)
        {
            f.Write("</form>");
            f.Write("</body>\n");
            f.Write("</html>\n");
        }

        public void BuildHTMLHead(StreamWriter f, string formName)
        {
            f.Write("<html>\n");
            f.Write("<head>\n");
            f.Write("<h4 align=\"center\">Generated at: " + DateTime.Now + "</h4>\n");
            f.Write("<style type=text/css> { font-family: Verdana, Helvetica, sans-serif;  word-wrap: break-word; } h1 { font-family: Verdana, Helvetica, sans-serif; } h4 { margin-left: 3 em; font-family: Verdana, Helvetica, sans-serif; font-size: smaller } p{ font-size: smaller; } table { margin-left: 3 em; font-family: Verdana, Helvetica, sans-serif; font-size: smaller;} .deleted { font-family: Verdana, Helvetica, sans-serif; font-size: larger; color: #F3727B; } .added { font-family: Verdana, Helvetica, sans-serif; font-size: larger; color: #8ECF78; } .changed { font-family: Verdana, Helvetica, sans-serif; font-size: larger; color: #6C6CF9; } .nameColumnTitle { width: 30%; color: #FFFFFF; background: #3399FF } .oneValueColumnTitle { width: 70%; color: #FFFFFF; background: #3399FF } .modTwoColumnsTitle{ width: 35%; color: #FFFFFF; background: #3399FF } .nameColumn { width: 30%; background: lightyellow } .oneColumn { width: 70%; word-wrap: break-word; } .twoColumns { width: 35%; word-wrap: break-word; }</style>");
            f.Write("</head>\n");
            f.Write("<body>\n");
            f.Write("<form name=\"" + formName + "\">");
        }

        private void createDisplay(Dictionary<RdfId, List<RdfAttribute>> dict, string type, string cssClass)
        {
            foreach (KeyValuePair<RdfId, List<RdfAttribute>> pair in dict.OrderBy<KeyValuePair<RdfId, List<RdfAttribute>>, RdfId>(kvp => kvp.Key, new TypeComparer()))
            {
                string rdfId = pair.Key.GetRdfId();
                List<RdfAttribute> lst = pair.Value;
                this.f_all.Write("<h3 ID=" + rdfId + " class=" + cssClass + ">" + pair.Key.GetPath() + " (" + pair.Key.rdfType.Substring(pair.Key.rdfType.IndexOf(":") + 1) + ")</h3>");
                this.f_all.Write("<h4>Identification</h4>");
                this.addTableHeader(this.f_all);
                this.addRdfIdTable(this.f_all, pair.Key);
                this.f_all.Write("</table>");
                if (this.IsEmpty(lst))
                {
                    continue;
                }
                this.f_all.Write("<h4>Attributes & Links</h4>");
                this.addTableHeader(this.f_all);
                this.addAttributesTable(this.f_all);
                string str2 = type.ToLower();
                if (str2 != null)
                {
                    if (!(str2 == "added"))
                    {
                        if (str2 == "changed")
                        {
                            goto Label_032E;
                        }
                        if (str2 == "deleted")
                        {
                            goto Label_0341;
                        }
                    }
                    else
                    {
                        this.f_all.Write("<tr>");
                        this.f_all.Write("<td><a href=adds.html#" + rdfId + " target=\"AddAttributes\">Click Here to view all attributes.</a></td>");
                        this.f_all.Write("<td><p></p></td>\n");
                        this.f_all.Write("<td><p></p></td>\n");
                        this.f_all.Write("</tr>");
                        this.f_add.Write("<h3 ID=" + rdfId + " class=" + cssClass + ">" + pair.Key.GetPath() + " (" + pair.Key.rdfType.Substring(pair.Key.rdfType.IndexOf(":") + 1) + ")</h3>");
                        this.f_add.Write("<h4>" + type + " (" + pair.Key.rdfType + " - " + rdfId + " )</h4>");
                        this.addTableHeader(this.f_add);
                        this.addAttributesTable(this.f_add);
                        this.addAttributes(this.f_add, lst);
                        this.f_add.Write("</table>");
                    }
                }
                goto Label_04C5;
            Label_032E:
                this.addAttributes(this.f_all, lst);
                goto Label_04C5;
            Label_0341:
                this.f_all.Write("<tr>");
                this.f_all.Write("<td><a href=dels.html#" + rdfId + " target=\"DeleteAttributes\">Click Here to view all attributes.</a></td>");
                this.f_all.Write("<td><p></p></td>\n");
                this.f_all.Write("<td><p></p></td>\n");
                this.f_all.Write("</tr>");
                this.f_del.Write("<h3 ID=" + rdfId + " class=" + cssClass + ">" + pair.Key.GetPath() + " (" + pair.Key.rdfType.Substring(pair.Key.rdfType.IndexOf(":") + 1) + ")</h3>");
                this.f_del.Write("<h4>" + type + " (" + pair.Key.rdfType + " - " + rdfId + " )</h4>");
                this.addTableHeader(this.f_del);
                this.addAttributesTable(this.f_del);
                this.addAttributes(this.f_del, lst);
                this.f_del.Write("</table>");
            Label_04C5:
                this.f_all.Write("</table>");
            }
        }

        public void format(StreamWriter alf, StreamWriter adf, StreamWriter dlf)
        {
            this.f_all = alf;
            this.f_add = adf;
            this.f_del = dlf;
            this.BuildHTMLHead(this.f_all, "contents");
            this.BuildHTMLHead(this.f_add, "adds");
            this.BuildHTMLHead(this.f_del, "dels");
            this.addAdditions();
            this.addChanges();
            this.addDeletions();
            this.BuildHTMLFoot(this.f_all);
            this.BuildHTMLFoot(this.f_add);
            this.BuildHTMLFoot(this.f_del);
        }

        public bool IsEmpty(List<RdfAttribute> lst)
        {
            bool flag = false;
            if (lst.Count == 1)
            {
                flag = true;
                foreach (RdfAttribute attribute in lst)
                {
                    if (attribute.attributeName != null)
                    {
                        return false;
                    }
                }
            }
            return flag;
        }

    }
}